package reznic.ga.tracker;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import reznic.ga.tracker.interfaces.ProtocolBuilder;
import reznic.ga.tracker.objects.Config;
import reznic.ga.tracker.objects.RequestData;
import reznic.ga.tracker.objects.TrackEvent;
import reznic.ga.tracker.objects.TrackItem;
import reznic.ga.tracker.objects.TrackMobileApp;
import reznic.ga.tracker.objects.TrackPageview;

/**
 *
 * @author zloy
 */
public class JGoogleTracker {

    private final Config config;
    private ProtocolBuilder builder;
    private ExecutorService pool = Executors.newCachedThreadPool();

    /**
     *
     * @param config
     */
    public JGoogleTracker(Config config) {
        this.config = config;
        createBuilder();
    }

    private void createBuilder() {
        builder = new ProtocolBuilderV1(config);
    }

//============= MOBILE APP =====================
    public void trackMobileApp(String appName, String screenName) {
        trackMobileApp(-1, appName, screenName);
    }

    public void trackMobileApp(long userID, String appName, String screenName) {
        TrackMobileApp mobile = new TrackMobileApp();
        mobile.setAppName(appName);
        mobile.setScreenName(screenName);
        trackMobileApp(userID, mobile);
    }

    public void trackMobileApp(String appName) {
        trackMobileApp(-1, appName);
    }

    public void trackMobileApp(long userID, String appName) {
        TrackMobileApp mobile = new TrackMobileApp();
        mobile.setAppName(appName);
        trackMobileApp(userID, mobile);
    }

    public void trackMobileApp(TrackMobileApp mobileApp) {
        trackMobileApp(-1, mobileApp);
    }

    public void trackMobileApp(long userID, TrackMobileApp mobileApp) {
        RequestData data = new RequestData();
        data.setMobileApp(mobileApp);
        if (userID != -1) {
            data.getVisitor().setId(userID);
        }
        makeCustomRequest(data);
    }
//============= ITEM ===========================

    public void trackItem(long userID, String transactionID, String itemName) {
        TrackItem item = new TrackItem(transactionID, itemName);
        trackItem(userID, item);
    }

    /**
     * item track
     *
     * @param transactionID
     * @param itemName
     */
    public void trackItem(String transactionID, String itemName) {
        TrackItem item = new TrackItem(transactionID, itemName);
        trackItem(-1, item);
    }

    public void trackItem(long userID, TrackItem item) {
        RequestData data = new RequestData();
        data.setItem(item);
        if (userID != -1) {
            data.getVisitor().setId(userID);
        }
        makeCustomRequest(data);
    }
//============= EVENT ======================

    /**
     * new event for new user
     *
     * user serUserID
     *
     * @param category
     * @param action
     * @param label
     */
    public void trackEvent(String category, String action, String label) {
        trackEvent(-1, category, action, label);
    }

    public void trackEvent(long userID, String category, String action, String label) {
        TrackEvent ev = new TrackEvent(category, action);
        ev.setLabel(label);
        trackEvent(ev, userID);
    }

    public void trackEvent(long userID, String category, String action) {
        TrackEvent ev = new TrackEvent(category, action);
        trackEvent(ev, userID);
    }

    public void trackEvent(String category, String action) {
        trackEvent(-1, category, action);
    }

    public void trackEvent(TrackEvent event, long userID) {
        RequestData data = new RequestData();
        data.setEvent(event);
        if (userID != -1) {
            data.getVisitor().setId(userID);
        }
        makeCustomRequest(data);
    }

//============= PAGEVIEW ======================
    public void trackPageview(String hostName, String page) {
        trackPageview(-1, hostName, page);
    }

    public void trackPageview(long userID, String hostName, String page) {
        TrackPageview p = new TrackPageview(hostName, page, null);
        trackPageview(p, userID);
    }

    public void trackPageview(long userID, String hostName, String page, String title) {
        TrackPageview p = new TrackPageview(hostName, page, title);
        trackPageview(p, userID);
    }

    public void trackPageview(TrackPageview pageview, long userID) {
        RequestData data = new RequestData();
        data.setPageview(pageview);
        if (userID != -1) {
            data.getVisitor().setId(userID);
        }
        makeCustomRequest(data);
    }

    public synchronized void makeCustomRequest(final RequestData data) {
        if (data == null) {
            throw new NullPointerException("AppData is null");
        }
        if (builder == null) {
            throw new NullPointerException("buider class is null");
        }

        Thread th = new Thread() {
            @Override
            public void run() {
                try {
                    dispatchRequest(builder.build(data));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        };
        pool.execute(th);
    }

    private void dispatchRequest(String _url) {
        System.out.println("dispatchRequest: " + _url);
        try {
            URL url = new URL(_url);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setInstanceFollowRedirects(true);
            connection.connect();
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                System.out.printf("Tracking success for url '{}'", url);
            } else {
                System.out.printf("Error requesting url '{}', received response code {}", url, responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
